# Copyright (c) 2024, kaepyz@gmail.com and contributors
# For license information, please see license.txt

import frappe
from frappe.model.document import Document


class TongtoolOrderItem(Document):
	def validate(self):
		"""验证订单商品数据"""
		if self.quantity and self.quantity <= 0:
			frappe.throw("商品数量必须大于0")
		
		if self.transaction_price and self.transaction_price < 0:
			frappe.throw("交易价格不能为负数")
		
		# 如果有通途SKU，尝试自动匹配ERPNext物料
		if self.tongtool_sku and not self.erp_item_code:
			self.auto_match_erp_item()
	
	def auto_match_erp_item(self):
		"""自动匹配ERPNext物料"""
		try:
			# 使用现有的customer_items表进行匹配
			item_code = frappe.db.sql("""
				SELECT DISTINCT parent as item_code
				FROM `tabItem Customer Detail` 
				WHERE ref_code = %s
				ORDER BY 
					CASE 
						WHEN customer_name = '通途' THEN 1
						WHEN customer_group = '电商平台' THEN 2
						WHEN customer_name IS NULL AND customer_group IS NULL THEN 3
						ELSE 4
					END
				LIMIT 1
			""", (self.tongtool_sku,))
			
			if item_code:
				self.erp_item_code = item_code[0][0]
				self.match_status = '已匹配'
				
				# 获取物料成本
				self.update_item_costs()
			else:
				self.match_status = '未匹配'
				
		except Exception as e:
			frappe.log_error(f"自动匹配ERPNext物料失败: {str(e)}")
			self.match_status = '需人工处理'
	
	def update_item_costs(self):
		"""更新物料成本信息"""
		if not self.erp_item_code:
			return
		
		try:
			# 获取物料的当前成本
			item_cost = frappe.db.get_value(
				"Item Price", 
				{
					"item_code": self.erp_item_code,
					"price_list": "Standard Buying"
				}, 
				"price_list_rate"
			)
			
			if item_cost:
				self.item_cost = item_cost
			
			# 计算头程运费
			shipping_cost = self.calculate_shipping_cost()
			if shipping_cost:
				self.shipping_cost = shipping_cost
				
		except Exception as e:
			frappe.log_error(f"更新物料成本失败: {str(e)}")
	
	def calculate_shipping_cost(self):
		"""计算头程运费"""
		if not self.erp_item_code:
			return 0
		
		try:
			# 获取父文档的仓库信息来确定目的地
			parent_doc = self.get_parent_doc()
			if not parent_doc or not parent_doc.warehouse_name:
				return 0
			
			# 获取物料重量
			item_weight = frappe.get_cached_value("Item", self.erp_item_code, "weight_per_unit") or 0
			if item_weight <= 0:
				return 0
			
			# 根据仓库名称确定目的地代码
			destination = self.get_destination_code(parent_doc.warehouse_name)
			if not destination:
				return 0
			
			# 查找适用的物流价格
			logistic_price = frappe.db.get_value(
				"Logistic Price", 
				{
					"logistic_price_list": f"头程-CNSX-{destination}",
					"valid_from": ["<=", frappe.utils.today()],
					"valid_upto": [">=", frappe.utils.today()]
				}, 
				["actual_weight_rate", "volumetric_weight_rate", "volumetric_divisor"]
			)
			
			if logistic_price:
				# 计算体积重量（需要物料尺寸信息）
				item_volume = self.calculate_item_volume()
				volumetric_weight = item_volume / (logistic_price.volumetric_divisor or 6000)
				
				# 取较大值计费
				chargeable_weight = max(item_weight, volumetric_weight)
				
				if chargeable_weight == volumetric_weight and logistic_price.volumetric_weight_rate:
					return chargeable_weight * logistic_price.volumetric_weight_rate
				elif logistic_price.actual_weight_rate:
					return chargeable_weight * logistic_price.actual_weight_rate
			
			return 0
			
		except Exception as e:
			frappe.log_error(f"计算头程运费失败: {str(e)}")
			return 0
	
	def get_destination_code(self, warehouse_name):
		"""根据仓库名称获取目的地代码"""
		warehouse_mapping = {
			'美东': 'USNJ',
			'美中': 'USTX', 
			'波兰': 'PL',
			'日本': 'JPFBA',
			'美国': 'USFBA',
			'德国': 'DEFBA',
			'英国': 'UKFBA'
		}
		
		for keyword, code in warehouse_mapping.items():
			if keyword in warehouse_name:
				return code
		
		return None
	
	def calculate_item_volume(self):
		"""计算物料体积"""
		if not self.erp_item_code:
			return 0
		
		try:
			# 从重量模板获取尺寸信息
			weight_template_code = f"ZLMB#{self.erp_item_code.split('-')[0]}"
			if len(self.erp_item_code.split('-')) >= 3:
				weight_template_code += f"-{'-'.join(self.erp_item_code.split('-')[1:3])}"
			
			volume_data = frappe.db.get_value(
				"Item",
				weight_template_code,
				["custom_item_length", "custom_item_width", "custom_item_height"]
			)
			
			if volume_data and all(volume_data):
				length, width, height = volume_data
				return (length * width * height) / 1000000  # 转换为立方米
			
			return 0
			
		except Exception as e:
			frappe.log_error(f"计算物料体积失败: {str(e)}")
			return 0
